//package kt.flows
//
//import kotlinx.coroutines.*
//import kotlinx.coroutines.channels.*
//import kotlinx.coroutines.selects.select
//import kotlin.random.Random
//
///**
// *
// * select 表达式
// * 1，选择性的基础
// * selectFizzBuzz 一次只会执行一个，当ReceiveChannel 在 delay 时将不会执行  onReceive
// * [baseSelectChannel]
// *
// *
// * 2,当channel close 时的select ,
// * [closeWhenSelect]
// *
// *
// * 3, 已发送
// * [sendedNumber]
// *
// *
// * 4, Select 延迟值
// * [delaySendChannel]
// *
// *
// * 5,在延迟值通道上切换
// * [switchChannelChannelDemo]
// *
// * @see[https://book.kotlincn.net/text/select-expression.html]
// *
// *
// */
//fun main() {
////    baseSelectChannel()
////    closeWhenSelect()
////    sendedNumber()
////    delaySendChannel()
//    switchChannelChannelDemo()
//}
//
////------------------------------------------------------
////------------------------------------------------------
//
//
//fun CoroutineScope.switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String> {
//    var current = input.receive() // 从第一个接收到的延迟值开始
//    while (isActive) { // 循环直到被取消或关闭
//        val next = select<Deferred<String>?> { // 从这个 select 中返回下一个延迟值或 null
//            input.onReceiveCatching { update ->
//                update.getOrNull()
//            }
//            current.onAwait { value ->
//                send(value) // 发送当前延迟生成的值
//                input.receiveCatching().getOrNull() // 然后使用从输入通道得到的下一个延迟值
//            }
//        }
//        if (next == null) {
//            println("Channel was closed")
//            break // 跳出循环
//        } else {
//            current = next
//        }
//    }
//}
//
//fun CoroutineScope.asyncString(str: String, time: Long) = async {
//    delay(time)
//    str
//}
//
//
//
//fun switchChannelChannelDemo(){
//    runBlocking {
//        val chan = Channel<Deferred<String>>() // 测试使用的通道
//
//        launch { // 启动打印协程
//            for (s in switchMapDeferreds(chan))
//                println(s) // 打印每个获得的字符串
//        }
//
//        chan.send(asyncString("BEGIN", 100))
//        delay(200) // 充足的时间来生产 "BEGIN"
//
//        chan.send(asyncString("Slow", 500))
//        delay(100) // 不充足的时间来生产 "Slow"
//
//        chan.send(asyncString("Replace", 100))
//        delay(500) // 在最后一个前给它一点时间
//
//        chan.send(asyncString("END", 500))
//        delay(1000) // 给执行一段时间
//
//        chan.close() // 关闭通道……
//        delay(500) // 然后等待一段时间来让它结束
//
//    }
//
//}
//
//
//
////------------------------------------------------------
//fun CoroutineScope.asyncString(time: Int) = async {
//    delay(time.toLong())
//    "Waited for $time ms"
//}
//
//fun CoroutineScope.asyncStringsList(): List<Deferred<String>> {
//    val random = Random(3)
//    return List(12) { asyncString(random.nextInt(1000)) }
//}
//
//
//fun delaySendChannel(){
//    runBlocking {
//        val list = asyncStringsList()
//
//        val result = select<String> {
//            list.withIndex().forEach { (index, deferred) ->
//                deferred.onAwait { answer ->
//                    "Deferred $index produced answer '$answer'"
//                }
//            }
//        }
//
//        println(result)
//
//        val countActive = list.count { it.isActive }
//
//        println("$countActive coroutines are still active")
//
//    }
//}
//
//
////------------------------------------------------------
//
//fun CoroutineScope.produceNumbers(side : SendChannel<Int>) = produce<Int> {
//    for ( num in 1..10){
//        delay(100)
//        select<Unit> {
//            onSend(num){
//                println("on send $num")
//            }
//
//            side.onSend(num){
//                println("side .. on send $num")
//            }
//
//        }
//    }
//}
//
//fun sendedNumber(){
//
//    runBlocking {
//        val side = Channel<Int> ()
//
//        launch {
//            side.consumeEach {
//                println("side channel has $it")
//            }
//        }
//
//        produceNumbers(side).consumeEach {
//            println("consuming $it")
//            delay(250)
//
//        }
//
//        println("done consuming ...")
//        coroutineContext.cancelChildren()
//    }
//
//}
//
//
//
//
//
//
//
//
////------------------------------------------------------
//suspend fun selectAorB(a : ReceiveChannel<String> , b : ReceiveChannel<String>) : String =
//    select<String> {
//
//        a.onReceiveCatching{
//            val value = it.getOrNull()
//            if (value != null){
//                "a -> $value"
//            }else{
//                "channel a is null"
//            }
//
//        }
//        b.onReceiveCatching {
//            val value = it.getOrNull()
//            if (value != null) {
//                "b -> $value"
//            } else {
//                "channel b is null"
//            }
//
//        }
//
//    }
//
//
//fun closeWhenSelect(){
//    runBlocking {
//
//        val a = produce<String> {
//            repeat(4){
//                send("hello $it")
//            }
//        }
//
//        val b = produce<String> {
//            repeat(4) {
//                send("world $it")
//            }
//        }
//
//        repeat(8){
//            println(selectAorB(a , b))
//        }
//
//        coroutineContext.cancelChildren()
//
//    }
//
//}
///*
//                a -> hello 0
//                a -> hello 1
//                b -> world 0
//                a -> hello 2
//                a -> hello 3
//                b -> world 1
//                channel a is null
//                channel a is null
// */
//
//
////------------------------------------------------------
//
//var counterIndex = 0
//
//fun CoroutineScope.fizz() = produce<String> {
//    while (true) { // 每 500 毫秒发送一个 "Fizz"
//        delay(500)
//        send("Fizz")
//    }
//}
//
//fun CoroutineScope.buzz() = produce<String> {
//    while (true) { // 每 1000 毫秒发送一个 "Buzz!"
//        delay(1000)
//        send("Buzz!")
//    }
//}
//
//suspend fun selectFizzBuzz(fizz: ReceiveChannel<String>, buzz: ReceiveChannel<String>) {
//    select<Unit> { // <Unit> 意味着该 select 表达式不返回任何结果
//        println("前select index = ${counterIndex} ; fizz = $fizz ; buzz = $buzz ")
//
//        fizz.onReceive { value ->  // 这是第一个 select 子句
//            println("fizz -> '$value'")
//        }
//
//        println("中select index = $counterIndex ")
//        buzz.onReceive { value ->  // 这是第二个 select 子句
//            println("buzz -> '$value'")
//        }
//
//        println("后select index = $counterIndex ")
//
//        counterIndex ++
//    }
//}
//
//fun baseSelectChannel() {
//    runBlocking {
//
//        val fizz = fizz()
//        val buzz = buzz()
//
//        repeat(7) {
//            selectFizzBuzz(fizz, buzz)
//        }
//        coroutineContext.cancelChildren() // 取消 fizz 和 buzz 协程
//    }
//}
//
///*
//
//fizz -> 'Fizz'
//buzz -> 'Buzz!'
//fizz -> 'Fizz'
//fizz -> 'Fizz'
//buzz -> 'Buzz!'
//fizz -> 'Fizz'
//fizz -> 'Fizz'
//
// */
//
////------------------------------------------------------
//
//
//
//
//
//
//
//
//
//fun demos() {
//    runBlocking {
//
//    }
//}